home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume14 / mush6.0 / part02 < prev    next >
Encoding:
Internet Message Format  |  1988-04-12  |  51.4 KB

  1. Subject:  v14i034:  Mail User's Shell, version 6.0, Part02/14
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: island!argv@sun.com (Dan Heller)
  7. Posting-number: Volume 14, Issue 34
  8. Archive-name: mush6.0/part02
  9.  
  10.  
  11.  
  12. #! /bin/sh
  13. # This is a shell archive.  Remove anything before this line, then unpack
  14. # it by saving it into a file and typing "sh file".  To overwrite existing
  15. # files, type "sh file -c".  You can also feed this as standard input via
  16. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  17. # will see the following message at the end:
  18. #        "End of archive 2 (of 14)."
  19. # Contents:  aliases.c expr.c folders.c hdr_panel.c hdr_procs.c print.c
  20. #   rite.c sort.c strings.c tool.c
  21. # Wrapped by rsalz@fig.bbn.com on Wed Apr 13 20:04:42 1988
  22. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  23. if test -f 'aliases.c' -a "${1}" != "-c" ; then 
  24.   echo shar: Will not clobber existing file \"'aliases.c'\"
  25. else
  26. echo shar: Extracting \"'aliases.c'\" \(4558 characters\)
  27. sed "s/^X//" >'aliases.c' <<'END_OF_FILE'
  28. X/* (c) copyright @(#)aliases.c    2.4    10/15/86 (Dan Heller) */
  29. X
  30. X#include "mush.h"
  31. X
  32. X/*
  33. X * do_alias handles aliases, header settings, functions, and fkeys.
  34. X * since they're all handled in the same manner, the same routine is
  35. X * used. argv[0] determines which to use.
  36. X * alias is given here as an example
  37. X *
  38. X * alias           identify all aliases
  39. X * alias name      identify alias
  40. X * alias name arg1 arg2 arg3... -> name="arg1 arg2 arg3"; call set_option
  41. X * unalias arg1 [arg2 arg3 ... ]        unalias args
  42. X *
  43. X * same is true for dealing with your own headers.
  44. X * (also the expand command)
  45. X * always return -1 since it nas no effect on messages
  46. X */
  47. do_alias(argc, argv)
  48. register char **argv;
  49. X{
  50. X    register char *cmd = *argv, *p;
  51. X    struct options **list;
  52. X    char firstchar = *cmd, buf[BUFSIZ];
  53. X
  54. X    if (argc == 0)
  55. X    return -1;
  56. X    if (firstchar == 'u')
  57. X    firstchar = cmd[2];
  58. X    if (*++argv && !strcmp(*argv, "-?")) { /* doesn't apply for fkeys */
  59. X    register char *help_str;
  60. X    if (firstchar == 'a' || firstchar == 'e')
  61. X        help_str = "alias";
  62. X    else if (firstchar == 'c')
  63. X        help_str = "func_help";
  64. X    else if (firstchar == 'f')
  65. X        help_str = "fkey_help";
  66. X    else
  67. X        help_str = "own_hdrs";
  68. X    return help(0, help_str, cmd_help);
  69. X    }
  70. X
  71. X    if (firstchar == 'a')
  72. X    list = &aliases;
  73. X    else if (firstchar == 'c')
  74. X    list = &functions;
  75. X    else if (firstchar == 'f')
  76. X    list = &fkeys;
  77. X    else
  78. X    list = &own_hdrs;
  79. X
  80. X    if (*cmd == 'u') {
  81. X    if (!*argv)
  82. X        print("%s what?\n", cmd);
  83. X    /* unset a list separated by spaces or ',' */
  84. X    else while (*argv) {
  85. X        if (!strcmp(*argv, "*")) /* unset everything */
  86. X        while (*list)
  87. X            (void) un_set(list, (*list)->option);
  88. X        else if (!un_set(list, *argv))
  89. X        print("\"%s\" isn't set\n", *argv);
  90. X        argv++;
  91. X    }
  92. X    return -1;
  93. X    }
  94. X
  95. X    if (!*argv && *cmd != 'e') {
  96. X    /* just type out all the aliases or own_hdrs */
  97. X    (void) do_set(*list, NULL);
  98. X    return -1;
  99. X    }
  100. X
  101. X    if (*cmd == 'e') {   /* command was "expand" (aliases only) */
  102. X    if (!*argv)
  103. X        print("expand which alias?\n");
  104. X    else
  105. X        do  {
  106. X        print("%s: ", *argv);
  107. X        if (p = alias_to_address(*argv))
  108. X            print("%s\n", p);
  109. X        } while (*++argv);
  110. X    return -1;
  111. X    }
  112. X
  113. X    /* at this point, *argv now points to a variable name ...
  114. X     * check for hdr -- if so, *argv better end with a ':' (check *p)
  115. X     */
  116. X    if (list == &own_hdrs && !(p = index(*argv, ':'))) {
  117. X    print("header labels must end with a ':' (%s)\n", *argv);
  118. X    return -1;
  119. X    }
  120. X    if (!argv[1] && !index(*argv, '='))
  121. X    if (p = do_set(*list, *argv))
  122. X        print("%s\n", p);
  123. X    else
  124. X        print("%s is not set\n", *argv);
  125. X    else {
  126. X    char *tmpargv[2];
  127. X    (void) argv_to_string(buf, argv);
  128. X    if ((p = any(buf, " \t=")) && *p != '=')
  129. X        *p = '=';
  130. X    /* if we're setting an alias, enforce the insertion of commas
  131. X     * between each well-formed address.
  132. X     */
  133. X    if (list == &aliases)
  134. X        fix_up_addr(p+1);
  135. X    tmpargv[0] = buf;
  136. X    tmpargv[1] = NULL;
  137. X    (void) add_option(list, tmpargv);
  138. X    }
  139. X    return -1;
  140. X}
  141. X
  142. X/* takes string 's' which can be a name or list of names separated by
  143. X * commas and checks to see if each is aliased to something else.
  144. X * return address of the static buf.
  145. X */
  146. char *
  147. alias_to_address(s)
  148. register char *s;
  149. X{
  150. X    static char buf[BUFSIZ];
  151. X    register char *p, *p2, *tmp;
  152. X    char newbuf[BUFSIZ], c;
  153. X    static int recursive;
  154. X
  155. X    if (!aliases)
  156. X    return strcpy(buf, s);
  157. X    if (!s || !*s) {
  158. X    print("No recipeints!?!\n");
  159. X    return NULL;
  160. X    }
  161. X    if (!recursive) {
  162. X    bzero(buf, BUFSIZ);
  163. X    p2 = buf;  /* if we're starting all this, p2 starts at &buf[0] */
  164. X    } else
  165. X    p2 = buf+strlen(buf);   /* else, pick up where we left off */
  166. X
  167. X    if (++recursive == 30) {
  168. X    print("alias references too many addresses!\n");
  169. X    recursive = 0;
  170. X    return NULL;
  171. X    }
  172. X    do  {
  173. X    if (!(p = get_name_n_addr(s, NULL, NULL)))
  174. X        break;
  175. X    c = *p, *p = 0;
  176. X
  177. X    /* if this is an alias, recurse this routine to expand it out */
  178. X    if ((tmp = do_set(aliases, s)) && *tmp) {
  179. X        if (!alias_to_address(strcpy(newbuf, tmp))) {
  180. X        *p = c;
  181. X        return NULL;
  182. X        } else
  183. X        p2 = buf+strlen(buf);
  184. X    /* Now, make sure the buffer doesn't overflow */
  185. X    } else if (strlen(s) + (p2-buf) + 2 > BUFSIZ) {  /* add " "  + NULL */
  186. X        print("address length too long.\n");
  187. X        recursive = 0;
  188. X        *p = c;
  189. X        return NULL;
  190. X    } else {
  191. X        /* append the new alias (or unchanged address) onto the buffer */
  192. X        p2 += Strcpy(p2, s);
  193. X        *p2++ = ',', *p2++ = ' ';
  194. X    }
  195. X    for (*p = c; *p == ',' || isspace(*p); p++)
  196. X        ;
  197. X    } while (*(s = p));
  198. X    if (recursive)
  199. X    recursive--;
  200. X    if (!recursive)
  201. X    *(p2-2) = 0;  /* get rid of last ", " if end of recursion */
  202. X    return buf;
  203. X}
  204. END_OF_FILE
  205. if test 4558 -ne `wc -c <'aliases.c'`; then
  206.     echo shar: \"'aliases.c'\" unpacked with wrong size!
  207. fi
  208. # end of 'aliases.c'
  209. fi
  210. if test -f 'expr.c' -a "${1}" != "-c" ; then 
  211.   echo shar: Will not clobber existing file \"'expr.c'\"
  212. else
  213. echo shar: Extracting \"'expr.c'\" \(4061 characters\)
  214. sed "s/^X//" >'expr.c' <<'END_OF_FILE'
  215. X/* @(#)expr.c    2.3    (c) copyright 10/15/86 (Dan Heller) */
  216. X
  217. X#include "mush.h"
  218. X
  219. char *eval_expr();
  220. X
  221. X/* Parse a string (p) to interpret numbers and ranges of numbers (n-m)
  222. X * delimited by whitespace or comma's. Set msg_list bitfields using
  223. X * macros in mush.h.
  224. X * Return the address of the end of whatever we parsed (in case there's
  225. X * more that the calling routine cares to deal with).
  226. X * Finally, remember that user specifies one more than actual message number
  227. X */
  228. char *
  229. do_range(p, list1)
  230. register char *p, *list1;
  231. X{
  232. X    register int num1 = -1, num2 = -1, except = 0;
  233. X    register char *p2;
  234. X    char list2[MAXMSGS_BITS];
  235. X
  236. X    if (!p)
  237. X    return "";
  238. X    while (*p) {
  239. X    if (isdigit(*p) || *p == '$' || *p == '.' || *p == '^') {
  240. X        if (isdigit(*p)) {
  241. X        char c;
  242. X        p2 = p;
  243. X        skipdigits(0);  /* find the end of the digits */
  244. X        c = *p, *p = 0; /* temporarily plug a null */
  245. X        if (!(num2 = chk_msg(p2))) {
  246. X            clear_msg_list(list1);
  247. X            return NULL;
  248. X        }
  249. X        *p = c;
  250. X        } else if (*p == '$')
  251. X        p++, num2 = msg_cnt;
  252. X        else if (*p == '.')
  253. X        p++, num2 = current_msg+1;
  254. X        else if (*p == '^')
  255. X        p++, num2 = 1;
  256. X        if (except)
  257. X        unset_msg_bit(list1, num2-1);
  258. X        else
  259. X        set_msg_bit(list1, num2-1);
  260. X        if (num1 >= 0) {
  261. X        if (num1 > num2) {
  262. X            print("syntax error: range sequence order reversed.\n");
  263. X            clear_msg_list(list1);
  264. X            return NULL;
  265. X        }
  266. X        while (++num1 < num2)
  267. X            if (except)
  268. X            unset_msg_bit(list1, num1-1);
  269. X            else
  270. X            set_msg_bit(list1, num1-1);
  271. X        num1 = num2 = -1;
  272. X        }
  273. X    }
  274. X    /* expressions to evaluate start with a `
  275. X     * p2 points to first char passed the last char parsed.
  276. X     */
  277. X    if (*p == '`') {
  278. X        clear_msg_list(list2);
  279. X        if (!(p = eval_expr(p, list2))) {
  280. X        clear_msg_list(list1);
  281. X        return NULL;
  282. X        } else {
  283. X        if (except)
  284. X            bitput(list2, list1, msg_cnt, &=~) /* MACRO */
  285. X        else
  286. X            bitput(list2, list1, msg_cnt, |=) /* MACRO */
  287. X        }
  288. X    }
  289. X    /* NOT operator: `* {5}' (everything except for 5)
  290. X     * `4-16 {8-10}'  (4 thru 16 except for 8,9,10)
  291. X     */
  292. X    if (*p == '{' || *p == '}') {
  293. X        if (*p == '{' && (except || num1 >= 0))
  294. X        break;
  295. X        if (*p == '}' && !except) {
  296. X        print("syntax error: missing {\n"); /* } */
  297. X        break;
  298. X        }
  299. X        except = !except;
  300. X    } else if (*p == '-')
  301. X        if (num1 >= 0 || !index(" \t{},.*`$", *(p+1)) && !isdigit(*(p+1)))
  302. X        break;
  303. X        else
  304. X        num1 = num2;
  305. X    else if (*p == ',' || *p == '*') {
  306. X        if (num1 >= 0)
  307. X        break;
  308. X        else if (*p == '*') {
  309. X        if (except)
  310. X            clear_msg_list(list1);
  311. X        else
  312. X            for (num1 = 0; num1 < msg_cnt; num1++)
  313. X            set_msg_bit(list1, num1);
  314. X        num1 = -1;
  315. X        }
  316. X    } else if (!index(" \t`", *p))
  317. X        break;
  318. X    if (*p)
  319. X        skipspaces(1); /* don't make user type stuff squished together */
  320. X    }
  321. X    if (num1 >= 0 || except) {
  322. X    if (except)
  323. X  /* { */   print("syntax error: unmatched }\n");
  324. X    else
  325. X        print("syntax error: unfinished range\n");
  326. X    clear_msg_list(list1);
  327. X    return NULL;
  328. X    }
  329. X    return p;
  330. X}
  331. X
  332. X/* evaluate expressions:
  333. X * mail> delete `pick -f root`     deletes all messages from root.
  334. X * mail> save { `pick -s "Re:"` }  save all message that don't have "Re:"
  335. X *                   in the subject header.
  336. X * mail> save `pick -x -s "Re:"`   same
  337. X * args as follows:
  338. X *   p should point to the first ` -- check for it.
  339. X *   on tells whether to turn bits on or off if messages match.
  340. X */
  341. char *
  342. eval_expr(p, new_list)
  343. register char *p, new_list[];
  344. X{
  345. X    register char *p2, **argv;
  346. X    int       argc;
  347. X    u_long      save_flags = glob_flags;
  348. X
  349. X    if (!(p2 = index(++p, '`'))) {
  350. X    print("unmatched backquote (`)\n");
  351. X    return NULL;
  352. X    }
  353. X    *p2 = 0;
  354. X
  355. X    skipspaces(0);
  356. X    if (!*p) {
  357. X    print("Invalid null command\n");
  358. X    return NULL;
  359. X    }
  360. X    turnon(glob_flags, DO_PIPE);
  361. X    /* ignore sigs only because if user interrupts the do_command,
  362. X     * the long jump will corrupt the stack and the program is hosed.
  363. X     * fix is to have layers of jumpbuf's to return to different levels.
  364. X     */
  365. X    turnon(glob_flags, IGN_SIGS);
  366. X    if (*p && (argv = make_command(p, TRPL_NULL, &argc)))
  367. X    (void) do_command(argc, argv, new_list);
  368. X    glob_flags = save_flags;
  369. X    *p2 = '`';
  370. X    return p2+1;
  371. X}
  372. END_OF_FILE
  373. if test 4061 -ne `wc -c <'expr.c'`; then
  374.     echo shar: \"'expr.c'\" unpacked with wrong size!
  375. fi
  376. # end of 'expr.c'
  377. fi
  378. if test -f 'folders.c' -a "${1}" != "-c" ; then 
  379.   echo shar: Will not clobber existing file \"'folders.c'\"
  380. else
  381. echo shar: Extracting \"'folders.c'\" \(5662 characters\)
  382. sed "s/^X//" >'folders.c' <<'END_OF_FILE'
  383. X/* @(#)folders.c    (c) copyright 10/18/86 (Dan Heller) */
  384. X
  385. X#include "mush.h"
  386. X
  387. X/* folder %[user]  --new mailfile is the spool/mail/login file [user].
  388. X * folder #  --new mailfile is the folder previous to the current folder
  389. X * folder &  --new mailfile is ~/mbox (or whatever "mbox" is set to)
  390. X * folder +file --new mailfile is in the directory "folder"; name is 'file'
  391. X * folder "path" --full path name or the one in current working directory.
  392. X *
  393. X * in all cases, changes are updated unless a '!' is specified after the
  394. X * folder command (e.g. "f!", "folder !" "fo!" .. all permutations)
  395. X * as usual, if new mail has arrived before the file is copied back, then
  396. X * user will be notified beforehand.
  397. X *
  398. X * RETURN -1 on error -- else return 0. All bits in msg_list are set to true.
  399. X */
  400. folder(argc, argv, list)
  401. register char **argv, list[];
  402. X{
  403. X    int n, updating = !strcmp(*argv, "update"), do_read_only = 0, no_hdrs = 0;
  404. X    static char oldfolder[MAXPATHLEN];
  405. X    char *tmp, *newfolder = NULL, buf[MAXPATHLEN];
  406. X    struct stat statbuf;
  407. X
  408. X    if (ison(glob_flags, DO_PIPE)) {
  409. X    print("You can't pipe to the folder command.\n");
  410. X    return -1;
  411. X    }
  412. X    while (*++argv && (**argv == '-' || **argv == '!'))
  413. X    if (!strcmp(*argv, "-?"))
  414. X        return help(0, "folder_help", cmd_help);
  415. X    else if (!strcmp(*argv, "-N"))
  416. X        no_hdrs = 1;
  417. X    else if (!strcmp(*argv, "-r"))
  418. X        do_read_only = 1;
  419. X    else if (!strcmp(*argv, "!"))
  420. X        turnoff(glob_flags, DO_UPDATE);
  421. X
  422. X    if (updating) {
  423. X    (void) strcpy(buf, mailfile);
  424. X    if (ison(glob_flags, READ_ONLY))
  425. X        do_read_only = 1;
  426. X    } else {
  427. X    if (!*argv) {
  428. X        mail_status(0);
  429. X        return 0;
  430. X    }
  431. X    if (!strcmp(*argv, "#"))
  432. X        if (!*oldfolder) {
  433. X        print("No previous folder\n");
  434. X        return -1;
  435. X        } else
  436. X        newfolder = oldfolder;
  437. X    else if (!strcmp(*argv, "&")) {
  438. X        if (!(newfolder = do_set(set_options, "mbox")) || !*newfolder)
  439. X        newfolder = DEF_MBOX;
  440. X    } else
  441. X        newfolder = *argv;
  442. X    n = 0;
  443. X    tmp = getpath(newfolder, &n);
  444. X    if (n == -1) {
  445. X        print("%s: %s\n", newfolder, tmp);
  446. X        return -1;
  447. X    } else if (n == 1) {
  448. X        print("%s: is a directory\n", tmp);
  449. X        return -1;
  450. X    }
  451. X    /* strcpy so copyback() below (which calls getpath) doesn't change
  452. X     * the data that tmp intended to point to.
  453. X     */
  454. X    (void) strcpy(buf, tmp);
  455. X    }
  456. X    if (stat(buf, &statbuf) == -1 || !(statbuf.st_mode & 0400)) {
  457. X    error("Unable to read %s", buf);
  458. X    return -1;
  459. X    }
  460. X    /* If the file can't be opened for writing, autoset READ_ONLY */
  461. X    if (!(statbuf.st_mode & 0200))
  462. X    do_read_only = 1;
  463. X#ifdef SUNTOOL
  464. X    if (istool) lock_cursors();
  465. X#endif /* SUNTOOL */
  466. X    if (ison(glob_flags, DO_UPDATE) && !copyback()) {
  467. X#ifdef SUNTOOL
  468. X    if (istool) unlock_cursors();
  469. X#endif /* SUNTOOL */
  470. X    /* could be an error, but new mail probably came in */
  471. X    return -1;
  472. X    }
  473. X    if (!updating)
  474. X    (void) strcpy(oldfolder, mailfile);
  475. X    strdup(mailfile, buf);
  476. X    do_read_only? turnon(glob_flags,READ_ONLY) : turnoff(glob_flags,READ_ONLY);
  477. X    last_size = spool_size = 0L;
  478. X    msg_cnt = 0;
  479. X    turnoff(glob_flags, CONT_PRNT);
  480. X
  481. X    turnon(glob_flags, IGN_SIGS);
  482. X    /* clear the tempfile */
  483. X    fclose(tmpf);
  484. X    if (!do_read_only) {
  485. X    if (!(tmpf = fopen(tempfile, "w"))) {
  486. X        error("error truncating %s", tempfile);
  487. X        turnoff(glob_flags, IGN_SIGS);
  488. X        return -1;
  489. X    }
  490. X    } else if (!(tmpf = fopen(mailfile, "r"))) {
  491. X    error(mailfile);
  492. X    return -1;
  493. X    }
  494. X    getmail();
  495. X    last_msg_cnt = msg_cnt;  /* for check_new_mail */
  496. X    (void) mail_size();
  497. X#ifdef SUNTOOL
  498. X    if (istool) {
  499. X    panel_set(next_scr, PANEL_SHOW_ITEM, FALSE, 0);
  500. X    panel_set(prev_scr, PANEL_SHOW_ITEM, FALSE, 0);
  501. X    pw_rop(hdr_win, 0,0, hdr_rect.r_width, hdr_rect.r_height,PIX_CLR,0,0,0);
  502. X    if (!msg_cnt) {
  503. X        add_folder_to_menu(folder_item, 3);
  504. X        add_folder_to_menu(save_item, 1);
  505. X    }
  506. X    }
  507. X#endif /* SUNTOOL */
  508. X    current_msg = 0;
  509. X    turnoff(glob_flags, IGN_SIGS);
  510. X
  511. X    /* now sort messages according a user_defined default */
  512. X    if (!updating && msg_cnt > 1 && !strcmp(mailfile, spoolfile) &&
  513. X        (tmp = do_set(set_options, "sort"))) {
  514. X    (void) sprintf(buf, "sort %s", tmp);
  515. X    if (argv = make_command(buf, TRPL_NULL, &argc)) {
  516. X        /* msg_list can't be null for do_command and since we're not
  517. X         * interested in the result, call sort directly
  518. X         */
  519. X        (void) sort(argc, argv, NULL);
  520. X        free_vec(argv);
  521. X    }
  522. X    }
  523. X    turnoff(glob_flags, DO_UPDATE);
  524. X
  525. X    /* go to first NEW message */
  526. X    while (current_msg < msg_cnt && ison(msg[current_msg].m_flags, OLD))
  527. X    current_msg++;
  528. X    if (current_msg == msg_cnt)
  529. X    /* no new message found -- try first unread message */
  530. X    for (current_msg = 0;
  531. X         current_msg < msg_cnt && isoff(msg[current_msg].m_flags, UNREAD);
  532. X         current_msg++)
  533. X         ;
  534. X    if (current_msg == msg_cnt)
  535. X    current_msg = 0;
  536. X
  537. X    if ((!istool || istool && !msg_cnt) && !iscurses)
  538. X    mail_status(0);
  539. X    /* be quite if we're piping */
  540. X    if ((istool || !updating) && isoff(glob_flags, IS_PIPE) &&
  541. X    (istool || !no_hdrs) && msg_cnt)
  542. X    (void) cmd_line(sprintf(buf, "headers %d", current_msg+1), msg_list);
  543. X#ifdef SUNTOOL
  544. X    if (istool) {
  545. X    if (!msg_cnt)
  546. X        print("No Mail in %s\n", mailfile);
  547. X    if (!getting_opts)
  548. X        if (msg_cnt && isoff(glob_flags, IS_GETTING))
  549. X        display_msg(current_msg, (long)0);
  550. X        else
  551. X        do_clear();
  552. X    unlock_cursors();
  553. X    }
  554. X#endif /* SUNTOOL */
  555. X    if (list) {
  556. X    clear_msg_list(list);
  557. X    bitput(list, list, msg_cnt, =~) /* macro */
  558. X    }
  559. X    return 0;
  560. X}
  561. X
  562. folders(argc, argv)
  563. register char **argv;
  564. X{
  565. X    register char *p;
  566. X    char buf[128], unused[MAXMSGS_BITS];
  567. X
  568. X    if (!(p = do_set(set_options, "folder")) || !*p)
  569. X    p = DEF_FOLDER;
  570. X    (void) sprintf(buf, "ls %s", p);
  571. X    if (argv = make_command(buf, TRPL_NULL, &argc))
  572. X    (void) do_command(argc, argv, unused);
  573. X    return -1;
  574. X}
  575. END_OF_FILE
  576. if test 5662 -ne `wc -c <'folders.c'`; then
  577.     echo shar: \"'folders.c'\" unpacked with wrong size!
  578. fi
  579. # end of 'folders.c'
  580. fi
  581. if test -f 'hdr_panel.c' -a "${1}" != "-c" ; then 
  582.   echo shar: Will not clobber existing file \"'hdr_panel.c'\"
  583. else
  584. echo shar: Extracting \"'hdr_panel.c'\" \(4107 characters\)
  585. sed "s/^X//" >'hdr_panel.c' <<'END_OF_FILE'
  586. X/* @(#)hdr_panel.c    (c) copyright    10/18/86 (Dan Heller) */
  587. X
  588. X#include "mush.h"
  589. X
  590. make_hdr_panel(choice_args, button_args)
  591. char **choice_args, **button_args;
  592. X{
  593. X    hdr_panel_sw = panel_create(tool,
  594. X    PANEL_HEIGHT, 30,
  595. X    0);
  596. X    hdr_panel = (Panel)hdr_panel_sw->ts_data;
  597. X
  598. X    msg_num_item = panel_create_item(hdr_panel, PANEL_TEXT,
  599. X    PANEL_ATTRIBUTE_LIST,        choice_args,
  600. X    PANEL_ITEM_X,            4,
  601. X    PANEL_ITEM_Y,            4,
  602. X    PANEL_LABEL_STRING,        "Range:",
  603. X    PANEL_MENU_CHOICE_STRINGS,     "Help", 0,
  604. X    PANEL_VALUE_DISPLAY_LENGTH,     10,
  605. X    PANEL_VALUE_STORED_LENGTH,     80,
  606. X    PANEL_LABEL_FONT,         fonts[DEFAULT],
  607. X    PANEL_NOTIFY_STRING,         "\n\r",
  608. X    PANEL_NOTIFY_PROC,         msg_num_done,
  609. X    0);
  610. X
  611. X    sub_hdr_item[0] = panel_create_item(hdr_panel, PANEL_CHOICE,
  612. X    PANEL_ATTRIBUTE_LIST,         choice_args,
  613. X    PANEL_ITEM_X,            149,
  614. X    PANEL_ITEM_Y,            4,
  615. X    PANEL_LABEL_IMAGE,            &mouse_left,
  616. X    PANEL_CHOICE_STRINGS,         "Help", 0,
  617. X    PANEL_NOTIFY_PROC,            read_mail,
  618. X    0);
  619. X    sub_hdr_item[1] = panel_create_item(hdr_panel, PANEL_CHOICE,
  620. X    PANEL_ATTRIBUTE_LIST,         choice_args,
  621. X    PANEL_ITEM_X,            174,
  622. X    PANEL_ITEM_Y,            4,
  623. X    PANEL_LABEL_STRING,           "Read ",
  624. X    PANEL_MENU_TITLE_IMAGE,     &mouse_left,
  625. X    PANEL_CHOICE_STRINGS,        "Help", 0,
  626. X    PANEL_NOTIFY_PROC,            read_mail,
  627. X    0);
  628. X    sub_hdr_item[2] = panel_create_item(hdr_panel, PANEL_CHOICE,
  629. X    PANEL_ATTRIBUTE_LIST,         choice_args,
  630. X    PANEL_ITEM_X,            223,
  631. X    PANEL_ITEM_Y,            4,
  632. X    PANEL_LABEL_IMAGE,            &mouse_middle,
  633. X    PANEL_CHOICE_STRINGS,         "Help", 0,
  634. X    PANEL_NOTIFY_PROC,            delete_mail,
  635. X    0);
  636. X    sub_hdr_item[3] = panel_create_item(hdr_panel, PANEL_CHOICE,
  637. X    PANEL_ATTRIBUTE_LIST,         choice_args,
  638. X    PANEL_ITEM_X,            248,
  639. X    PANEL_ITEM_Y,            4,
  640. X    PANEL_LABEL_STRING,           "Delete ",
  641. X    PANEL_MENU_TITLE_IMAGE,     &mouse_middle,
  642. X    PANEL_CHOICE_STRINGS,         "Help", 0,
  643. X    PANEL_NOTIFY_PROC,            delete_mail,
  644. X    0);
  645. X    sub_hdr_item[4] = panel_create_item(hdr_panel, PANEL_CHOICE,
  646. X    PANEL_ATTRIBUTE_LIST,         choice_args,
  647. X    PANEL_ITEM_X,            313,
  648. X    PANEL_ITEM_Y,            4,
  649. X    PANEL_LABEL_IMAGE,            &mouse_right,
  650. X    PANEL_CHOICE_STRINGS,         "Help", 0,
  651. X    PANEL_NOTIFY_PROC,            read_mail,
  652. X    0);
  653. X    sub_hdr_item[5] = panel_create_item(hdr_panel, PANEL_CHOICE,
  654. X    PANEL_ATTRIBUTE_LIST,         choice_args,
  655. X    PANEL_ITEM_X,            338,
  656. X    PANEL_ITEM_Y,            4,
  657. X    PANEL_LABEL_STRING,           "Menu ",
  658. X    PANEL_MENU_TITLE_IMAGE,            &mouse_right,
  659. X    PANEL_CHOICE_STRINGS,         "Help", 0,
  660. X    PANEL_NOTIFY_PROC,            read_mail,
  661. X    0);
  662. X
  663. X    hdr_display = panel_create_item(hdr_panel, PANEL_CHOICE,
  664. X    PANEL_ATTRIBUTE_LIST,         choice_args,
  665. X    PANEL_ITEM_X,            387,
  666. X    PANEL_ITEM_Y,            4,
  667. X    PANEL_LABEL_IMAGE,
  668. X        panel_button_image(hdr_panel, "Display", 7, fonts[DEFAULT]),
  669. X    PANEL_MENU_TITLE_STRING,     "Header Display Formats",
  670. X    PANEL_CHOICE_STRINGS,         "Show Deleted Messages",
  671. X                    "Don't Show Deleted Messages",
  672. X                    "Current Header in Bold Text",
  673. X                    "Current Header in Reverse Text",
  674. X                    "Help",
  675. X                    0,
  676. X    PANEL_NOTIFY_PROC,         display_hdrs,
  677. X    0);
  678. X
  679. X    ignore_item = panel_create_item(hdr_panel, PANEL_CHOICE,
  680. X    PANEL_ATTRIBUTE_LIST, choice_args,
  681. X    PANEL_ITEM_X,            464,
  682. X    PANEL_ITEM_Y,            4,
  683. X    PANEL_LABEL_IMAGE,
  684. X        panel_button_image(hdr_panel, "Headers", 7, fonts[DEFAULT]),
  685. X    PANEL_MENU_TITLE_STRING,     "Ignored Headers",
  686. X    PANEL_CHOICE_STRINGS,         "Current Settings",
  687. X                    "Add Values",
  688. X                    "Delete Values",
  689. X                    "Help",
  690. X                    0,
  691. X    PANEL_NOTIFY_PROC,         p_set_opts,
  692. X    0);
  693. X
  694. X    next_scr = panel_create_item(hdr_panel, PANEL_CHOICE,
  695. X    PANEL_ATTRIBUTE_LIST,         choice_args,
  696. X    PANEL_ITEM_X,            541,
  697. X    PANEL_ITEM_Y,            4,
  698. X    PANEL_LABEL_IMAGE,
  699. X        panel_button_image(hdr_panel, "Next", 4, fonts[DEFAULT]),
  700. X    PANEL_MENU_TITLE_STRING,     "Display Message Headers",
  701. X    PANEL_CHOICE_STRINGS,         "Show Next screenful",
  702. X                    "Show Previous screenful",
  703. X                    0,
  704. X    PANEL_SHOW_ITEM,         FALSE,
  705. X    PANEL_NOTIFY_PROC,        do_hdr,
  706. X    0);
  707. X
  708. X    prev_scr = panel_create_item(hdr_panel, PANEL_CHOICE,
  709. X    PANEL_ATTRIBUTE_LIST,         choice_args,
  710. X    PANEL_ITEM_X,            594,
  711. X    PANEL_ITEM_Y,            4,
  712. X    PANEL_LABEL_IMAGE,
  713. X        panel_button_image(hdr_panel, "Prev", 4, fonts[DEFAULT]),
  714. X    PANEL_MENU_TITLE_STRING,     "Display Message Headers",
  715. X    PANEL_CHOICE_STRINGS,         "Show Previous screenful",
  716. X                    "Show Next screenful",
  717. X                    0,
  718. X    PANEL_SHOW_ITEM,         FALSE,
  719. X    PANEL_NOTIFY_PROC,         do_hdr,
  720. X    0);
  721. X}
  722. END_OF_FILE
  723. if test 4107 -ne `wc -c <'hdr_panel.c'`; then
  724.     echo shar: \"'hdr_panel.c'\" unpacked with wrong size!
  725. fi
  726. # end of 'hdr_panel.c'
  727. fi
  728. if test -f 'hdr_procs.c' -a "${1}" != "-c" ; then 
  729.   echo shar: Will not clobber existing file \"'hdr_procs.c'\"
  730. else
  731. echo shar: Extracting \"'hdr_procs.c'\" \(4239 characters\)
  732. sed "s/^X//" >'hdr_procs.c' <<'END_OF_FILE'
  733. X/* @(#)hdr_procs.c    (c) copyright    10/18/86 (Dan Heller) */
  734. X
  735. X/* hdr_procs.c  -- panel item procedures for the message hdrs */
  736. X#include "mush.h"
  737. X
  738. X/* which message headers are to be displayed */
  739. do_hdr(foo, value, event)
  740. Panel_item foo;
  741. int value;
  742. struct inputevent *event;
  743. X{
  744. X    register char *argv[3];
  745. X    argv[2] = NULL;
  746. X    argv[0] = "headers";
  747. X
  748. X    if (!msg_cnt) {
  749. X    print("No Mail.");
  750. X    return;
  751. X    }
  752. X    if (!value || event->ie_code == MS_LEFT)
  753. X    argv[1] = (foo == next_scr)? "+": "-";
  754. X    else
  755. X    argv[1] = (foo == next_scr)? "-": "+";
  756. X
  757. X    panel_set(foo, PANEL_VALUE, 0, 0);
  758. X    (void) do_hdrs(2, argv, NULL);
  759. X}
  760. X
  761. X/* alters display of the message headers */
  762. display_hdrs(foo, value, event)
  763. Panel_item foo;
  764. int value;
  765. struct inputevent *event;
  766. X{
  767. X    int show_deleted = !!do_set(set_options, "show_deleted");
  768. X
  769. X    if (event->ie_code != MS_LEFT) {
  770. X    switch(value) {
  771. X        case 0 : case 1: {
  772. X        char buf[25];
  773. X        show_deleted = !value;
  774. X        (void) cmd_line(sprintf(buf, "%sset show_deleted",
  775. X            (value == 0)? "" : "un"), msg_list);
  776. X        }
  777. X        when 2 :
  778. X        turnoff(glob_flags, REV_VIDEO);
  779. X        when 3 :
  780. X        turnon(glob_flags, REV_VIDEO);
  781. X        when 4:
  782. X        return help(hdr_panel_sw->ts_windowfd, "headers", tool_help);
  783. X    }
  784. X    (void) do_hdrs(0, DUBL_NULL, NULL);
  785. X    }
  786. X    print("%sShow Deleted headers, \"Current Message\" header in %s",
  787. X            (show_deleted)? NO_STRING: "Don't ",
  788. X            (ison(glob_flags, REV_VIDEO))? "reverse": "boldface");
  789. X}
  790. X
  791. p_set_opts(item, value, event)
  792. Panel_item item;
  793. int value;
  794. struct inputevent *event;
  795. X{
  796. X    static char   *p, *oldp;
  797. X    static char   buf[8];
  798. X    u_long bang = ison(glob_flags, IGN_BANG);
  799. X
  800. X    if (event->ie_code == MS_LEFT)
  801. X    value = 0;
  802. X    if (value && (value != 3 || value != 2)
  803. X          && panel_get(input_item, PANEL_SHOW_ITEM)) {
  804. X    print("Need value for %s first!", oldp);
  805. X    return;
  806. X    } else if (!value && ison(glob_flags, IS_GETTING)) {
  807. X    print("Finish editing letter first");
  808. X    return;
  809. X    } else if (item == option_item) {
  810. X    if (!value) /* first menu item */
  811. X        view_options();
  812. X    else if (value == 1)
  813. X        set_fkeys();
  814. X    else
  815. X        (void) help(panel_sw->ts_windowfd, "opts", tool_help);
  816. X    return;
  817. X    } else if (item == ignore_item)
  818. X    if (value == 3)
  819. X        return help(hdr_panel_sw->ts_windowfd, "ignore", tool_help);
  820. X    else
  821. X        oldp = p = strcpy(buf, "ignore");
  822. X    else if (item == alias_item)
  823. X    if (value == 3)
  824. X        return help(panel_sw->ts_windowfd, "aliases", tool_help);
  825. X    else
  826. X        oldp = p = strcpy(buf, "alias");
  827. X    if (value) {
  828. X    char tmp[30];
  829. X    (void) sprintf(tmp, "%set %s:", (value == 1)? "S": "Uns", p);
  830. X    panel_set(input_item,
  831. X        PANEL_LABEL_STRING, tmp,
  832. X        PANEL_MENU_CHOICE_STRINGS, "Abort", 0,
  833. X        PANEL_SHOW_ITEM, TRUE,
  834. X        0);
  835. X    oldp = p;
  836. X    return;
  837. X    }
  838. X    panel_set(item, PANEL_VALUE, 0, 0);
  839. X    do_clear();
  840. X    pw_text(msg_win, l_width(DEFAULT), 15, PIX_SRC, fonts[LARGE], p);
  841. X    if (item != ignore_item)
  842. X    pw_text(msg_win, 30*l_width(DEFAULT),15,PIX_SRC,fonts[LARGE],"Values");
  843. X    turnon(glob_flags, IGN_BANG);
  844. X    (void) cmd_line(p, msg_list);
  845. X    if (!bang)
  846. X    turnoff(glob_flags, IGN_BANG);
  847. X}
  848. X
  849. msg_num_done(item, event)
  850. Panel_item item;
  851. struct inputevent *event;
  852. X{
  853. X    char buf[82];
  854. X    u_long bang = ison(glob_flags, IGN_BANG);
  855. X    register char *p;
  856. X    int n;
  857. X
  858. X    if (event->ie_code != '\n' && event->ie_code != '\r')
  859. X    return help(hdr_panel_sw->ts_windowfd, "message range", tool_help);
  860. X    (void) sprintf(buf, "headers %s", (p = (char *)panel_get_value(item)));
  861. X    panel_set(item, PANEL_VALUE, NO_STRING, 0);
  862. X    if (!(n = chk_msg(p)))
  863. X    return;
  864. X    current_msg = --n;
  865. X    turnon(glob_flags, IGN_BANG);
  866. X    (void) cmd_line(buf, msg_list);
  867. X    if (!bang)
  868. X    turnoff(glob_flags, IGN_BANG);
  869. X    display_msg(n, (long)0);
  870. X}
  871. X
  872. do_sort(item, value, event)
  873. Panel_item item;
  874. int value;
  875. struct inputevent *event;
  876. X{
  877. X    register char *argv[3];
  878. X    argv[0] = "sort";
  879. X    argv[2] = NULL;
  880. X    if (event->ie_code == MS_LEFT)
  881. X    argv[1] = do_set(set_options, "sort");
  882. X    else switch(value) {
  883. X    case 0: argv[1] = "d";
  884. X    when 1: argv[1] = "a";
  885. X    when 2: argv[1] = "s";
  886. X    when 3: argv[1] = "S";
  887. X    when 4: argv[1] = "R";
  888. X    when 5: help(hdr_panel_sw->ts_windowfd, "sort", tool_help);
  889. X    }
  890. X    if (value != 5) {
  891. X    (void) sort(2, argv, NULL);
  892. X    (void) do_hdrs(0, DUBL_NULL, NULL);
  893. X    }
  894. X    panel_set(item, PANEL_VALUE, 0, 0);
  895. X}
  896. END_OF_FILE
  897. if test 4239 -ne `wc -c <'hdr_procs.c'`; then
  898.     echo shar: \"'hdr_procs.c'\" unpacked with wrong size!
  899. fi
  900. # end of 'hdr_procs.c'
  901. fi
  902. if test -f 'print.c' -a "${1}" != "-c" ; then 
  903.   echo shar: Will not clobber existing file \"'print.c'\"
  904. else
  905. echo shar: Extracting \"'print.c'\" \(4945 characters\)
  906. sed "s/^X//" >'print.c' <<'END_OF_FILE'
  907. X/* @(#)print.c    2.4    (c) copyright 10/15/86 (Dan Heller) */
  908. X
  909. X#include "mush.h"
  910. X#include <varargs.h>
  911. X
  912. X/*ARGSUSED*/
  913. X/*VARARGS1*/
  914. void
  915. error(fmt, arg1, arg2, arg3, arg4)
  916. register char *fmt;
  917. char *arg1, *arg2, *arg3, *arg4;
  918. X{
  919. X    print(fmt, arg1, arg2, arg3, arg4);
  920. X    print_more(": %s\n", sys_errlist[errno]);
  921. X}
  922. X
  923. X#if defined(SUNTOOL) || defined(CURSES)
  924. X/*
  925. X * print just like printf -- to a window, to curses, or to stdout.  Use vprintf
  926. X * if available.  msgbuf is the buffer used to print into if necessary.
  927. X * If you're running SUN3.2 or higher, the typecast (unsigned char *)msgbuf
  928. X * (where indicated) otherwise, msgbuf is not typecast at all.
  929. X * Also note same casting in wprint().
  930. X */
  931. X/*VARARGS1*/
  932. void
  933. print(fmt, va_alist)
  934. register char *fmt;
  935. va_dcl
  936. X{
  937. X    static char msgbuf[BUFSIZ];
  938. X    va_list args;
  939. X#ifndef VPRINTF
  940. X    FILE foo;
  941. X#endif /* VPRINTF */
  942. X    static int x; /* position on line saved for continued prints */
  943. X    char *p; /* same type as struct file _ptr,_buf in stdio.h */
  944. X
  945. X    va_start(args); /* have args point to the beginning of argument stack */
  946. X
  947. X#ifdef CURSES
  948. X    if (iscurses) {
  949. X    if (isoff(glob_flags, CONT_PRNT))
  950. X        move(LINES-1, x = 0), refresh();
  951. X    } else
  952. X#endif /* CURSES */
  953. X    if (istool < 2) {
  954. X#ifdef VPRINTF
  955. X        vprintf(fmt, args);
  956. X#else /* VPRINTF */
  957. X        _doprnt(fmt, args, stdout);
  958. X#endif /* VPRINTF */
  959. X        fflush(stdout);
  960. X        va_end(args);
  961. X        return;
  962. X    }
  963. X#ifdef VPRINTF
  964. X    if (fmt)
  965. X    vsprintf(msgbuf, fmt, args); /* NULL in fmt reprints last msg */
  966. X#else /* VPRINTF */
  967. X    foo._cnt = BUFSIZ;
  968. X    foo._base = foo._ptr = msgbuf; /* may have to be cast(unsigned char *) */
  969. X    foo._flag = _IOWRT+_IOSTRG;
  970. X    if (fmt) {   /* passing NULL (not "") reprints last message */
  971. X    (void) _doprnt(fmt, args, &foo);
  972. X    *foo._ptr = '\0'; /* plant terminating null character */
  973. X    }
  974. X#endif /* VPIRNTF */
  975. X    va_end(args);
  976. X    p = msgbuf;
  977. X    if (iscurses || istool)
  978. X    while (p = index(p, '\n'))
  979. X        *p = ' ';
  980. X#ifdef CURSES
  981. X    if (iscurses) {
  982. X    p = msgbuf;
  983. X    for (;;) {
  984. X        int len = COLS-1-x; /* space remaining at till the eol */
  985. X        /* don't wrap the line! Just print it and refresh() */
  986. X        printw("%-.*s", len, p), clrtoeol(), refresh();
  987. X        /* if length(p) (remainder of msgbuf) doesn't wrap, break loop */
  988. X        if ((x += strlen(p)) < COLS-1)
  989. X        break;
  990. X        /* the next print will overwrite bottom line, so \n first */
  991. X        putchar('\n'), move(LINES-1, x = 0); /* reset x */
  992. X        /* move p forward the number of chars we were able to display */
  993. X        p += len;
  994. X        turnon(glob_flags, CNTD_CMD); /* display ...continue... prompt */
  995. X    }
  996. X    turnoff(glob_flags, CONT_PRNT);
  997. X    return;
  998. X    }
  999. X#endif /* CURSES */
  1000. X#ifdef SUNTOOL
  1001. X    if (isoff(glob_flags, CONT_PRNT))
  1002. X    x = 5;
  1003. X    turnoff(glob_flags, CONT_PRNT);
  1004. X    pw_text(print_win, x,   l_height(LARGE), PIX_SRC, fonts[LARGE], msgbuf);
  1005. X    pw_text(print_win, x+1, l_height(LARGE), PIX_SRC|PIX_DST,
  1006. X               fonts[LARGE], msgbuf);
  1007. X    x += strlen(msgbuf) * l_width(LARGE);
  1008. X    Clrtoeol(print_win, x, l_height(LARGE), LARGE);
  1009. X#endif /* SUNTOOL */
  1010. X}
  1011. X#endif /* SUNTOOL || CURSES */
  1012. X
  1013. X#ifdef SUNTOOL
  1014. X/*VARARGS*/
  1015. void
  1016. wprint(fmt, va_alist)
  1017. register char *fmt;
  1018. va_dcl
  1019. X{
  1020. X#ifndef VPRINTF
  1021. X    FILE foo;
  1022. X#endif /* VPRINTF */
  1023. X    char msgbuf[BUFSIZ]; /* we're not getting huge strings */
  1024. X    va_list args;
  1025. X
  1026. X    va_start(args);
  1027. X
  1028. X    if (istool < 2) {
  1029. X#ifdef VPRINTF
  1030. X    vprintf(fmt, args);
  1031. X#else /* VPRINTF */
  1032. X    _doprnt(fmt, args, stdout);
  1033. X#endif /* VPRINTF */
  1034. X    va_end(args);
  1035. X    fflush(stdout);
  1036. X    return;
  1037. X    }
  1038. X    if (!fmt)
  1039. X    return;
  1040. X#ifdef VPRINTF
  1041. X    vsprintf(msgbuf, fmt, args); /* NULL in fmt reprints last msg */
  1042. X#else /* VPRINTF */
  1043. X    foo._cnt = BUFSIZ;
  1044. X    foo._base = foo._ptr = msgbuf; /* may have to typecast (unsigned char *) */
  1045. X    foo._flag = _IOWRT+_IOSTRG;
  1046. X    _doprnt(fmt, args, &foo); /* format like printf into msgbuf via foo */
  1047. X    *foo._ptr = '\0'; /* plant terminating null character */
  1048. X#endif /* VPRINTF */
  1049. X    Addstr(msgbuf);  /* addstr() will scroll if necessary */
  1050. X}
  1051. X
  1052. X/*
  1053. X * scroll the msg_win "lines"
  1054. X * if `lines' is negative (backwards scroll) msg_pix can't be NULL
  1055. X */
  1056. void
  1057. scroll_win(lines)
  1058. register int lines;
  1059. X{
  1060. X    register int y = lines * l_height(curfont);
  1061. X    if (txt.y + y < msg_rect.r_height)
  1062. X    y = 0;  /* temporary */
  1063. X    txt.x = 5;
  1064. X
  1065. X    if (msg_pix) {
  1066. X    if (txt.y + y >= msg_pix->pr_size.y - 5)
  1067. X        y = msg_pix->pr_size.y - txt.y;
  1068. X    still_more += y; /* let scrolling know where we are */
  1069. X    txt.y += y;
  1070. X    pw_rop(msg_win, 0, 5,
  1071. X           msg_rect.r_width, crt * l_height(curfont),
  1072. X           PIX_SRC, msg_pix, 0, txt.y - msg_rect.r_height + 3);
  1073. X    tool_more(NULL);
  1074. X    return;
  1075. X    }
  1076. X    /* y must be positive (forward scrolling) so we're scrolling typed
  1077. X     * text or something like that (~p, ~?, etc...)
  1078. X     */
  1079. X    pw_copy(msg_win, 0, 0,
  1080. X    msg_rect.r_width, msg_rect.r_height - y,
  1081. X    PIX_SRC, msg_win, 0, y);
  1082. X    pw_writebackground(msg_win, 0, msg_rect.r_height - y,
  1083. X    msg_rect.r_width, y, PIX_CLR);
  1084. X    txt.y -= y;
  1085. X}
  1086. X#endif /* SUNTOOL */
  1087. X
  1088. clr_bot_line()
  1089. X{
  1090. X    print("");
  1091. X}
  1092. END_OF_FILE
  1093. if test 4945 -ne `wc -c <'print.c'`; then
  1094.     echo shar: \"'print.c'\" unpacked with wrong size!
  1095. fi
  1096. # end of 'print.c'
  1097. fi
  1098. if test -f 'rite.c' -a "${1}" != "-c" ; then 
  1099.   echo shar: Will not clobber existing file \"'rite.c'\"
  1100. else
  1101. echo shar: Extracting \"'rite.c'\" \(4181 characters\)
  1102. sed "s/^X//" >'rite.c' <<'END_OF_FILE'
  1103. X/* rite.c    (c) copyright 1986 (Dan Heller) */
  1104. X
  1105. X#include "mush.h"
  1106. X
  1107. X#define LASTLINE       (msg_rect.r_height - l_height(LARGE)-5)
  1108. X
  1109. static char String[BUFSIZ];
  1110. static int count, overflow, save_orig_x;
  1111. X
  1112. char *
  1113. rite(c)
  1114. register char c;
  1115. X{
  1116. X    static int literal_next;
  1117. X
  1118. X    if (c == ltchars.t_lnextc || literal_next) {
  1119. X    if (literal_next)
  1120. X        Addch(c);
  1121. X    else /* don't call Addch to prevent cursor from advancing */
  1122. X        pw_char(msg_win, txt.x, txt.y, PIX_SRC, fonts[curfont], '^');
  1123. X    literal_next = !literal_next;
  1124. X    return NULL;
  1125. X    }
  1126. X    literal_next = 0;
  1127. X    if (c == _tty.sg_erase || c == CTRL(127) || c == CTRL(H)) {
  1128. X    if (count)
  1129. X        backspace();
  1130. X    } else if (c == _tty.sg_kill) {
  1131. X    if (count) {
  1132. X        Clrtoeol(msg_win, txt.x = save_orig_x, txt.y,curfont);
  1133. X        overflow = count = String[0] = 0;
  1134. X    }
  1135. X    } else if (c == ltchars.t_werasc)
  1136. X    while (count) {
  1137. X        char c = String[count-1];
  1138. X        backspace();
  1139. X        if (!count ||
  1140. X        isspace(String[count-1]) && !isspace(c) ||
  1141. X        !isalnum(String[count-1]) && isalnum(c))
  1142. X        break;
  1143. X    }
  1144. X    else if (c == '\n' || c == '\r' || c == 13) {
  1145. X    String[count] = 0;
  1146. X    if ((txt.y += l_height(curfont)) >= LASTLINE && !getting_opts)
  1147. X        scroll_win(1);
  1148. X    /* else Clrtoeol(msg_win, txt.x, txt.y, curfont); */
  1149. X    overflow = count = 0, txt.x = 5;
  1150. X    return String;
  1151. X    } else if (c == 12)
  1152. X    if (ison(glob_flags, IS_GETTING))
  1153. X        Addch(c);
  1154. X    else
  1155. X        do_clear();
  1156. X    else if (count == BUFSIZ-1)
  1157. X    print("Text too long for String!"), count--;
  1158. X    else if (c == '\t')
  1159. X    do Addch(' ');
  1160. X    while (count % 8 && count < BUFSIZ);
  1161. X    else
  1162. X    Addch(c);
  1163. X    return NULL;
  1164. X}
  1165. X
  1166. static
  1167. backspace()
  1168. X{
  1169. X    if (overflow) {
  1170. X    pw_text(msg_win, save_orig_x, txt.y, PIX_SRC, fonts[curfont],
  1171. X        &String[--overflow]);
  1172. X    Clrtoeol(msg_win, msg_rect.r_width-10-l_width(curfont), txt.y, curfont);
  1173. X    String[--count] = 0;
  1174. X    } else if ((txt.x -= l_width(curfont)) >= 5) {
  1175. X    if (iscntrl(String[count-1])) {
  1176. X        pw_char(msg_win, txt.x, txt.y, PIX_SRC, fonts[curfont], ' ');
  1177. X        txt.x -= l_width(curfont);
  1178. X    }
  1179. X    pw_char(msg_win, txt.x, txt.y, PIX_SRC, fonts[curfont], ' ');
  1180. X    String[--count] = 0;
  1181. X    } else
  1182. X    txt.x = 5;
  1183. X}
  1184. X
  1185. static
  1186. Addch(c)
  1187. register char c;
  1188. X{
  1189. X    extern char *_unctrl[];
  1190. X
  1191. X    if (!count)
  1192. X    save_orig_x = txt.x, bzero(String, BUFSIZ);
  1193. X    if (c > 31 && c != 127)
  1194. X    String[count++] = c;
  1195. X    else {
  1196. X    Addch('^'), count--;
  1197. X    Addch(_unctrl[c][1]);
  1198. X    String[count-1] = c;
  1199. X    return;
  1200. X    }
  1201. X    pw_char(msg_win, txt.x, txt.y, PIX_SRC, fonts[curfont], c);
  1202. X    if ((txt.x += l_width(curfont)) <= msg_rect.r_width-5-l_width(curfont))
  1203. X    return;
  1204. X    if (getting_opts) {
  1205. X    pw_text(msg_win, save_orig_x, txt.y, PIX_SRC, fonts[curfont],
  1206. X        &String[++overflow]);
  1207. X    txt.x -= l_width(curfont);
  1208. X    pw_char(msg_win, txt.x, txt.y, PIX_SRC, fonts[curfont], ' ');
  1209. X    } else {
  1210. X    txt.x = 5;
  1211. X    if ((txt.y += l_height(curfont)) >= LASTLINE)
  1212. X        scroll_win(1);
  1213. X    }
  1214. X}
  1215. X
  1216. Addstr(s)
  1217. register char *s;
  1218. X{
  1219. X    char buf[BUFSIZ];
  1220. X    register int cnt = 0, max_len;
  1221. X    register char *p = buf, newline = 0;
  1222. X
  1223. X    max_len = (msg_rect.r_width - 10) / l_width(curfont) + 1;
  1224. X
  1225. X    while ((*p = *s++) && *p != '\n' && cnt < max_len)
  1226. X    if (*p == '\t')
  1227. X        do *p++ = ' ';
  1228. X        while (++cnt % 8);
  1229. X    else p++, cnt++;
  1230. X    *p = 0;
  1231. X
  1232. X    if (*--s)
  1233. X    newline = *s, *s = 0; /* newline may or may not be a '\n' */
  1234. X    else
  1235. X    s = 0;
  1236. X
  1237. X    if (*buf) {
  1238. X    if (msg_pix) {
  1239. X        struct pr_prpos pixr;
  1240. X        pixr.pr = msg_pix;
  1241. X        pixr.pos = txt;
  1242. X        pf_text(pixr, PIX_SRC, fonts[curfont], buf);
  1243. X    } else
  1244. X        pw_text(msg_win, txt.x, txt.y, PIX_SRC, fonts[curfont], buf);
  1245. X    txt.x += cnt * l_width(curfont);
  1246. X    }
  1247. X    if (newline) {
  1248. X    if (newline != '\n')
  1249. X        *s = newline;
  1250. X    if ((txt.y += l_height(curfont)) >= LASTLINE && !msg_pix)
  1251. X        scroll_win(1);
  1252. X    txt.x = 5;
  1253. X    if (newline == '\n' && !*++s)
  1254. X        return;
  1255. X    Addstr(s);
  1256. X    }
  1257. X}
  1258. X
  1259. tool_more(p)
  1260. register char *p;
  1261. X{
  1262. X    int percent;
  1263. X    /* we are typing -- scrool the window */
  1264. X    if (!msg_pix) {
  1265. X    scroll_win(1);
  1266. X    return;
  1267. X    }
  1268. X    if (p)
  1269. X    print(p);
  1270. X    else {
  1271. X    if ((percent = (still_more * 100) / msg_pix->pr_size.y) >= 100)
  1272. X        print( "--End of Message %d--", current_msg+1);
  1273. X    else
  1274. X        print("--Message %d--(%d%%)", current_msg+1, percent);
  1275. X    if (ison(glob_flags, IS_GETTING))
  1276. X        print_more(" ('q' returns to type-in mode)");
  1277. X    }
  1278. X}
  1279. END_OF_FILE
  1280. if test 4181 -ne `wc -c <'rite.c'`; then
  1281.     echo shar: \"'rite.c'\" unpacked with wrong size!
  1282. fi
  1283. # end of 'rite.c'
  1284. fi
  1285. if test -f 'sort.c' -a "${1}" != "-c" ; then 
  1286.   echo shar: Will not clobber existing file \"'sort.c'\"
  1287. else
  1288. echo shar: Extracting \"'sort.c'\" \(5560 characters\)
  1289. sed "s/^X//" >'sort.c' <<'END_OF_FILE'
  1290. X/* sort.c 2.0    (c) copyright 1986 (Dan Heller) */
  1291. X
  1292. X#include "mush.h"
  1293. X/* #define MYQSORT */
  1294. X
  1295. static int order, ignore_case;
  1296. static jmp_buf sortbuf;
  1297. X
  1298. sort(argc, argv, list)
  1299. register int argc;
  1300. register char *argv[], list[];
  1301. X{
  1302. X    int status_cmp(), author_cmp(), date_cmp(), subject_cmp(), subj_with_re();
  1303. X    int (*oldint)(), (*oldquit)();
  1304. X    int (*how)() = status_cmp;
  1305. X    int n, offset = -1, range = 0;
  1306. X
  1307. X    order = 1, ignore_case = FALSE;
  1308. X
  1309. X    while (argc && *++argv) {
  1310. X    n = 0;
  1311. X    while (argv[0][n])
  1312. X        switch(argv[0][n++]) {
  1313. X        case '-': order = -1;
  1314. X        when 'd': how = date_cmp;
  1315. X        when 'a': how = author_cmp;
  1316. X        when 's': how = subject_cmp;
  1317. X        when 'R': how = subj_with_re;
  1318. X        when 'S': how = status_cmp;
  1319. X        when 'i': ignore_case = TRUE;
  1320. X        otherwise: return help(0, "sort_help", cmd_help);
  1321. X        }
  1322. X    }
  1323. X    if (msg_cnt <= 1) {
  1324. X    print("Not enough messages to sort.\n");
  1325. X    return -1;
  1326. X    }
  1327. X    on_intr();
  1328. X
  1329. X    if (list && ison(glob_flags, IS_PIPE)) {
  1330. X    for (n = 0; n < msg_cnt; n++)
  1331. X        if (msg_bit(list, n)) {
  1332. X        if (offset < 0)
  1333. X            offset = n;
  1334. X        range++;
  1335. X        } else if (offset >= 0)
  1336. X        break;
  1337. X    } else
  1338. X    offset = 0, range = msg_cnt;
  1339. X
  1340. X    if (range < 2)
  1341. X    print("Range not broad enough to sort anything\n");
  1342. X    else {
  1343. X    Debug("Sorting %d messages starting at message %d\n", range, offset+1);
  1344. X
  1345. X    if (setjmp(sortbuf) == 0)
  1346. X        qsort((char *)&msg[offset], range, sizeof (struct msg), how);
  1347. X    else
  1348. X        print("WARNING: Sorting interrupted: unpredictable order.\n");
  1349. X    turnon(glob_flags, DO_UPDATE);
  1350. X    }
  1351. X    off_intr();
  1352. X    return -1;
  1353. X}
  1354. X
  1355. X#ifdef MYQSORT
  1356. qsort(base, len, siz, compar)
  1357. register struct msg *base;
  1358. int (*compar)();
  1359. X{
  1360. X     register int i, swapping;
  1361. X     struct msg temp;
  1362. X
  1363. X     do  {
  1364. X     swapping = 0;
  1365. X     for (i = 0; i < len-1; ++i) {
  1366. X         if (compar(base+i, base+i+1) > 0) {
  1367. X         temp = base[i];
  1368. X         base[i] = base[i+1];
  1369. X         base[i+1] = temp;
  1370. X         swapping = 1;
  1371. X         }
  1372. X     }
  1373. X     } while (swapping);
  1374. X}
  1375. X#endif /* MYSORT */
  1376. X
  1377. status_cmp(msg1, msg2)
  1378. register struct msg *msg1, *msg2;
  1379. X{
  1380. X    if (ison(glob_flags, WAS_INTR))
  1381. X    longjmp(sortbuf, 1);
  1382. X    if (msg1 < msg || msg2 < msg) {
  1383. X    wprint("sort botch trying to sort %d and %d\n", msg1-msg, msg2-msg);
  1384. X    return 0;
  1385. X    }
  1386. X    if (msg1->m_flags == msg2->m_flags)
  1387. X        return 0;
  1388. X    if (ison(msg1->m_flags, DELETE) && isoff(msg2->m_flags, DELETE))
  1389. X    return order;
  1390. X    if (isoff(msg1->m_flags, DELETE) && ison(msg2->m_flags, DELETE))
  1391. X    return -order;
  1392. X    if (isoff(msg1->m_flags, OLD) && ison(msg2->m_flags, OLD))
  1393. X    return -order;
  1394. X    if (ison(msg1->m_flags, OLD) && isoff(msg2->m_flags, OLD))
  1395. X    return order;
  1396. X    if (ison(msg1->m_flags, UNREAD) && isoff(msg2->m_flags, UNREAD))
  1397. X    return -order;
  1398. X    if (isoff(msg1->m_flags, UNREAD) && ison(msg2->m_flags, UNREAD))
  1399. X    return order;
  1400. X    if (ison(msg1->m_flags,PRESERVE) && isoff(msg2->m_flags,PRESERVE))
  1401. X    return -order;
  1402. X    if (isoff(msg1->m_flags,PRESERVE) && ison(msg2->m_flags,PRESERVE))
  1403. X    return order;
  1404. X    if (ison(msg1->m_flags,REPLIED) && isoff(msg2->m_flags,REPLIED))
  1405. X    return -order;
  1406. X    if (isoff(msg1->m_flags,REPLIED) && ison(msg2->m_flags,REPLIED))
  1407. X    return order;
  1408. X
  1409. X    return order;
  1410. X}
  1411. X
  1412. author_cmp(msg1, msg2)
  1413. register struct msg *msg1, *msg2;
  1414. X{
  1415. X    char buf1[BUFSIZ], buf2[BUFSIZ];
  1416. X
  1417. X    if (ison(glob_flags, WAS_INTR))
  1418. X    longjmp(sortbuf, 1);
  1419. X    if (msg1 < msg || msg2 < msg) {
  1420. X    wprint("sort botch trying to sort %d and %d\n", msg1-msg, msg2-msg);
  1421. X    return 0;
  1422. X    }
  1423. X    (void) reply_to(msg1 - msg, 0, buf1); /* "0" for "author only" */
  1424. X    (void) reply_to(msg2 - msg, 0, buf2);
  1425. X    Debug("author: msg %d: %s, msg %d: %s\n", msg1-msg, buf1, msg2-msg, buf2);
  1426. X    if (ignore_case)
  1427. X    return lcase_strcmp(buf1, buf2) * order;
  1428. X    return strcmp(buf1, buf2) * order;
  1429. X}
  1430. X
  1431. X/*
  1432. X * Subject comparison ignoring Re:  subject_to() appends an Re: if there is
  1433. X * any subject whatsoever.
  1434. X */
  1435. subject_cmp(msg1, msg2)
  1436. register struct msg *msg1, *msg2;
  1437. X{
  1438. X    char buf1[BUFSIZ], buf2[BUFSIZ];
  1439. X
  1440. X    if (ison(glob_flags, WAS_INTR))
  1441. X    longjmp(sortbuf, 1);
  1442. X    if (msg1 < msg || msg2 < msg) {
  1443. X    wprint("sort botch trying to sort %d and %d\n", msg1-msg, msg2-msg);
  1444. X    return 0;
  1445. X    }
  1446. X    (void) subject_to(msg1 - msg, buf1);
  1447. X    (void) subject_to(msg2 - msg, buf2);
  1448. X    Debug("subjects: (%d): \"%s\" (%d): \"%s\"\n", msg1-msg,buf1,msg2-msg,buf2);
  1449. X    if (ignore_case)
  1450. X    return lcase_strcmp(buf1, buf2) * order;
  1451. X    return strcmp(buf1, buf2) * order;
  1452. X}
  1453. X
  1454. X/*
  1455. X * compare subject strings from two messages.
  1456. X * If Re is appended, so be it -- if user wants to ignore Re: use 'R' flag.
  1457. X */
  1458. subj_with_re(msg1, msg2)
  1459. register struct msg *msg1, *msg2;
  1460. X{
  1461. X    char buf1[BUFSIZ], buf2[BUFSIZ], *p;
  1462. X
  1463. X    if (ison(glob_flags, WAS_INTR))
  1464. X    longjmp(sortbuf, 1);
  1465. X    if (msg1 < msg || msg2 < msg) {
  1466. X    wprint("sort botch trying to sort %d and %d\n", msg1-msg, msg2-msg);
  1467. X    return 0;
  1468. X    }
  1469. X    if (!(p = header_field(msg1 - msg, "subject")))
  1470. X    p = "";
  1471. X    (void) strcpy(buf1, p);
  1472. X    if (!(p = header_field(msg2 - msg, "subject")))
  1473. X    p = "";
  1474. X    (void) strcpy(buf2, p);
  1475. X    Debug("subjects: (%d): \"%s\" (%d): \"%s\"\n",
  1476. X    msg1-msg, buf1, msg2-msg, buf2);
  1477. X    if (ignore_case)
  1478. X    return lcase_strcmp(buf1, buf2) * order;
  1479. X    return strcmp(buf1, buf2) * order;
  1480. X}
  1481. X
  1482. date_cmp(msg1, msg2)
  1483. register struct msg *msg1, *msg2;
  1484. X{
  1485. X    char buf1[11], buf2[11];
  1486. X
  1487. X    if (ison(glob_flags, WAS_INTR))
  1488. X    longjmp(sortbuf, 1);
  1489. X    if (msg1 < msg || msg2 < msg) {
  1490. X    wprint("sort botch trying to sort %d and %d\n", msg1-msg, msg2-msg);
  1491. X    return 0;
  1492. X    }
  1493. X    (void) strcpy(buf1, msg_date(msg1-msg));
  1494. X    (void) strcpy(buf2, msg_date(msg2-msg));
  1495. X    Debug("dates: msg %d: %s, msg %d: %s\n", msg1-msg, buf1, msg2-msg, buf2);
  1496. X    return strcmp(buf1, buf2) * order;
  1497. X}
  1498. END_OF_FILE
  1499. if test 5560 -ne `wc -c <'sort.c'`; then
  1500.     echo shar: \"'sort.c'\" unpacked with wrong size!
  1501. fi
  1502. # end of 'sort.c'
  1503. fi
  1504. if test -f 'strings.c' -a "${1}" != "-c" ; then 
  1505.   echo shar: Will not clobber existing file \"'strings.c'\"
  1506. else
  1507. echo shar: Extracting \"'strings.c'\" \(4729 characters\)
  1508. sed "s/^X//" >'strings.c' <<'END_OF_FILE'
  1509. X/* strings.c Copyrite(1988) Dan Heller */
  1510. X
  1511. X#include "mush.h"
  1512. X
  1513. X/*
  1514. X * lose the newline character, trailing whitespace, and return the end of p
  1515. X * test for '\n' separately since some _ctype_[] arrays may not have the
  1516. X * _S bit set for the newline character.  see <ctype.h> for more info.
  1517. X */
  1518. char *
  1519. no_newln(p)
  1520. register char *p;
  1521. X{
  1522. X    register char *p2 = p + strlen(p);    /* point it to the null terminator */
  1523. X
  1524. X    while (p2 > p && *--p2 == '\n' || isspace(*p2))
  1525. X    *p2 = 0;  /* get rid of newline and trailing spaces */
  1526. X    return p2;
  1527. X}
  1528. X
  1529. X/* find any character in string2 that's in string1 */
  1530. char *
  1531. any(s1, s2)
  1532. register char *s1, *s2;
  1533. X{
  1534. X    register char *p;
  1535. X    if (!s1 || !*s1 || !s2 || !*s2)
  1536. X    return NULL;
  1537. X    for( ; *s1; s1++) {
  1538. X    for(p = s2; *p; p++)
  1539. X        if (*p == *s1)
  1540. X        return s1;
  1541. X    }
  1542. X    return NULL;
  1543. X}
  1544. X
  1545. X/* check two lists of strings each of which contain substrings.
  1546. X * Each substring is delimited by any char in "delimeters"
  1547. X * return true if any elements in list1 are on list2.
  1548. X * thus:
  1549. X * string1 = "foo, bar, baz"
  1550. X * string2 = "foobar, baz, etc"
  1551. X * delimeters = ", \t"
  1552. X * example returns 1 because "baz" exists in both lists
  1553. X * NOTE: case is ignored.
  1554. X */
  1555. chk_two_lists(list1, list2, delimeters)
  1556. register char *list1, *list2, *delimeters;
  1557. X{
  1558. X    register char *p, c;
  1559. X    register int found = 0;
  1560. X
  1561. X    if (p = any(list1, delimeters)) {
  1562. X    for (p++; *p && index(delimeters, *p); p++)
  1563. X        ;
  1564. X    if (chk_two_lists(p, list2, delimeters))
  1565. X        return 1;
  1566. X    }
  1567. X    if (p = any(list2, delimeters)) {
  1568. X    for (p++; *p && index(delimeters, *p); p++)
  1569. X        ;
  1570. X    if (chk_two_lists(list1, p, delimeters))
  1571. X        return 1;
  1572. X    }
  1573. X    if (p) {
  1574. X    while (index(delimeters, *(p-1)))
  1575. X        --p;
  1576. X    c = *p, *p = 0;
  1577. X    }
  1578. X    found = !lcase_strcmp(list1, list2);
  1579. X    if (p)
  1580. X    *p = c;
  1581. X    return found;
  1582. X}
  1583. X
  1584. bzero(addr, size)
  1585. register char *addr;
  1586. register int size;
  1587. X{
  1588. X    while (size-- > 0)
  1589. X    addr[size] = 0;
  1590. X}
  1591. X
  1592. X/* do an atoi() on the string passed and return in "val" the decimal value.
  1593. X * the function returns a pointer to the location in the string that is not
  1594. X * a digit.
  1595. X */
  1596. char *
  1597. my_atoi(p, val)
  1598. register char *p;
  1599. register int *val;
  1600. X{
  1601. X    int positive = 1;
  1602. X
  1603. X    if (!p)
  1604. X    return NULL;
  1605. X    *val = 0;
  1606. X    if (*p == '-')
  1607. X    positive = -1, p++;
  1608. X    while (isdigit(*p))
  1609. X    *val = (*val) * 10 + *p++ - '0';
  1610. X    *val *= positive;
  1611. X    return p;
  1612. X}
  1613. X
  1614. X/* strcmp ignoring case */
  1615. lcase_strcmp(str1, str2)
  1616. register char *str1, *str2;
  1617. X{
  1618. X    while (*str1 && *str2)
  1619. X    if (lower(*str1) != lower(*str2))
  1620. X        break;
  1621. X    else
  1622. X        str1++, str2++;
  1623. X    return *str1 - *str2;
  1624. X}
  1625. X
  1626. X/* strcpy coverting everything to lower case (arbitrary) to ignore cases */
  1627. char *
  1628. lcase_strcpy(dst, src)
  1629. register char *dst, *src;
  1630. X{
  1631. X    register char *s = dst;
  1632. X
  1633. X    /* "lower" is a macro, don't incrment its argument! */
  1634. X    while (*dst++ = lower(*src))
  1635. X    src++;
  1636. X    return s;
  1637. X}
  1638. X
  1639. X/* this strcpy returns number of bytes copied */
  1640. Strcpy(dst, src)
  1641. register char *dst, *src;
  1642. X{
  1643. X    register int n = 0;
  1644. X    if (!dst || !src)
  1645. X    return 0;
  1646. X    while (*dst++ = *src++)
  1647. X    n++;
  1648. X    return n;
  1649. X}
  1650. X
  1651. void
  1652. xfree(cp)
  1653. char *cp;
  1654. X{
  1655. X    extern char end[];
  1656. X
  1657. X    if (cp >= end && cp < (char *) &cp && debug < 5)
  1658. X    free(cp);
  1659. X}
  1660. X
  1661. char *
  1662. savestr(s)
  1663. register char *s;
  1664. X{
  1665. X    register char *p;
  1666. X    char *malloc();
  1667. X    if (!s)
  1668. X    s = "";
  1669. X    if (!(p = malloc((unsigned) (strlen(s) + 1)))) {
  1670. X    error("out of memory saving %s", s);
  1671. X    return NULL;
  1672. X    }
  1673. X    return strcpy(p, s);
  1674. X}
  1675. X
  1676. void
  1677. free_vec(argv)
  1678. char **argv;
  1679. X{
  1680. X    register int n;
  1681. X    if (!argv)
  1682. X    return;
  1683. X    for (n = 0; argv[n]; n++)
  1684. X    xfree(argv[n]);
  1685. X    xfree((char *)argv);
  1686. X}
  1687. X
  1688. X/* copy a vector of stirngs into one string -- return the end of the string */
  1689. char *
  1690. argv_to_string(p, argv)
  1691. register char *p, **argv;
  1692. X{
  1693. X    register int i;
  1694. X    register char *ptr = p;
  1695. X
  1696. X    *p = 0;
  1697. X    if (!argv[0])
  1698. X    return "";
  1699. X    for (i = 0; argv[i]; i++)
  1700. X    ptr += strlen(sprintf(ptr, "%s ", argv[i]));
  1701. X    *--ptr = 0;   /* get rid of the last space */
  1702. X    return ptr;
  1703. X}
  1704. X
  1705. X/* echo the command line. return -1 cuz no messages are affected */
  1706. do_echo(argc, argv)
  1707. register char **argv;
  1708. X{
  1709. X    char buf[BUFSIZ];
  1710. X    int no_return;
  1711. X
  1712. X    if (argc > 1 && !strcmp(argv[1], "-?")) {
  1713. X    print("usage: %s [-n] ...\n", *argv);
  1714. X    return -1;
  1715. X    }
  1716. X    no_return = *++argv && !strcmp(*argv, "-n");
  1717. X    (void) argv_to_string(buf, argv+no_return);
  1718. X    print("%s%s", buf, (no_return)? "" : "\n");
  1719. X    return -1;
  1720. X}
  1721. X
  1722. char *
  1723. itoa(n)
  1724. X{
  1725. X    static char buf[10];
  1726. X    return sprintf(buf, "%d", n);
  1727. X}
  1728. X
  1729. X#ifdef SYSV
  1730. char *
  1731. Sprintf(buf, fmt, args)
  1732. register char *buf, *fmt;
  1733. X{
  1734. X    vsprintf(buf, fmt, &args);
  1735. X    return buf;
  1736. X}
  1737. X#endif /* SYSV */
  1738. X
  1739. print_argv(argv)
  1740. char **argv;
  1741. X{
  1742. X    while (*argv)
  1743. X    if (debug)
  1744. X        printf("(%s) ", *argv++);
  1745. X    else
  1746. X        wprint("%s ", *argv++);
  1747. X    if (debug) {
  1748. X    putchar('\n');
  1749. X    fflush(stdout);
  1750. X    } else
  1751. X    wprint("\n");
  1752. X}
  1753. END_OF_FILE
  1754. if test 4729 -ne `wc -c <'strings.c'`; then
  1755.     echo shar: \"'strings.c'\" unpacked with wrong size!
  1756. fi
  1757. # end of 'strings.c'
  1758. fi
  1759. if test -f 'tool.c' -a "${1}" != "-c" ; then 
  1760.   echo shar: Will not clobber existing file \"'tool.c'\"
  1761. else
  1762. echo shar: Extracting \"'tool.c'\" \(4177 characters\)
  1763. sed "s/^X//" >'tool.c' <<'END_OF_FILE'
  1764. X/* @(#)tool.c    (c) copyright    10/15/86 (Dan Heller) */
  1765. X
  1766. X/* tool.c --make the mailtool windows, panels, etc... */
  1767. X#include "mush.h"
  1768. X
  1769. make_tool(args)
  1770. char **args;
  1771. X{
  1772. X    struct stat rootbuf, tmpbuf;
  1773. X    struct inputmask im;
  1774. X    register unsigned i;
  1775. X    char **choice_args, **button_args, *p;
  1776. X    char buf1[WIN_NAMESIZE], buf2[WIN_NAMESIZE];
  1777. X
  1778. X    getfonts();
  1779. X    mail_icon.ic_font = fonts[DEFAULT];
  1780. X
  1781. X    if (p = do_set(set_options, "screen_win"))
  1782. X    screen = atoi(p);
  1783. X    else
  1784. X    screen = 6;
  1785. X
  1786. X    /* where to place text on mail icon -- how many messages there are */
  1787. X    rect_construct(&mail_icon.ic_textrect,
  1788. X    l_width(DEFAULT), 58-l_height(DEFAULT),
  1789. X    3*l_width(DEFAULT), l_height(DEFAULT));
  1790. X
  1791. X    if (!(tool = tool_make(
  1792. X    WIN_ICON,         &mail_icon,
  1793. X    WIN_HEIGHT,         700,
  1794. X    WIN_WIDTH,         650,
  1795. X    WIN_BOUNDARY_MGR,     1,
  1796. X    WIN_ATTR_LIST,         args,
  1797. X    NULL)))
  1798. X    perror(prog_name), cleanup(0);
  1799. X    tool_free_attribute_list(args);
  1800. X
  1801. X    choice_args = panel_make_list(
  1802. X    PANEL_MENU_TITLE_FONT, fonts[LARGE],
  1803. X    PANEL_DISPLAY_LEVEL, PANEL_NONE,
  1804. X    PANEL_SHOW_MENU, TRUE,
  1805. X    PANEL_SHOW_MENU_MARK, FALSE,
  1806. X    0);
  1807. X
  1808. X    button_args = panel_make_list(
  1809. X    PANEL_FEEDBACK, PANEL_INVERTED,
  1810. X    PANEL_SHOW_MENU, FALSE,
  1811. X    0);
  1812. X
  1813. X    make_hdr_panel(choice_args, button_args);
  1814. X
  1815. X    if (!(hdr_sw = gfxsw_createtoolsubwindow(tool, "hdr_sw",
  1816. X    TOOL_SWEXTENDTOEDGE, 10+ screen*l_height(DEFAULT), (char **)0)))
  1817. X    perror("hdr_sw"), cleanup(0);
  1818. X    gfxsw_getretained((struct gfxsubwindow *)hdr_sw->ts_data);
  1819. X    hdr_win = ((struct gfxsubwindow *)(hdr_sw->ts_data))->gfx_pixwin;
  1820. X
  1821. X    input_imnull(&im);
  1822. X    win_setinputcodebit(&im, LOC_STILL);
  1823. X    win_setinputcodebit(&im, LOC_MOVE);
  1824. X    win_setinputcodebit(&im, LOC_WINENTER);
  1825. X    for (i = VKEY_FIRSTFUNC; i <= VKEY_LASTFUNC; i++)
  1826. X    win_setinputcodebit(&im, i);
  1827. X    win_setinputmask(hdr_sw->ts_windowfd, &im, &im,
  1828. X                   win_fdtonumber(hdr_panel_sw->ts_windowfd)); 
  1829. X    hdr_sw->ts_io.tio_selected = hdr_io;
  1830. X    hdr_sw->ts_io.tio_handlesigwinch = hdrwin_handlesigwinch;
  1831. X
  1832. X    make_main_panel(choice_args, button_args);
  1833. X    xfree(choice_args), xfree(button_args);
  1834. X
  1835. X    if (!(print_sw = gfxsw_createtoolsubwindow(tool, "print_sw",
  1836. X    TOOL_SWEXTENDTOEDGE, l_height(LARGE) + 10, (char **)0)))
  1837. X    perror("print_sw"), cleanup(0);
  1838. X    print_win = ((struct gfxsubwindow *)(print_sw->ts_data))->gfx_pixwin;
  1839. X    print_sw->ts_io.tio_handlesigwinch = print_sigwinch;
  1840. X
  1841. X    /* text subwindow */
  1842. X    if (!(msg_sw = gfxsw_createtoolsubwindow(tool, "msg_sw",
  1843. X    TOOL_SWEXTENDTOEDGE, TOOL_SWEXTENDTOEDGE, (char **)0)))
  1844. X    perror("msg_sw"), cleanup(0);
  1845. X    gfxsw_getretained((struct gfxsubwindow *)msg_sw->ts_data);
  1846. X    msg_win = ((struct gfxsubwindow *)(msg_sw->ts_data))->gfx_pixwin;
  1847. X
  1848. X    /* everything we want the text window to pay attention to */
  1849. X    input_imnull(&im);
  1850. X    im.im_flags = IM_ASCII;
  1851. X    im.im_flags &= ~IM_ANSI;
  1852. X    for (i = VKEY_FIRSTFUNC; i <= VKEY_LASTFUNC; i++)
  1853. X    win_setinputcodebit(&im, i);
  1854. X    win_setinputmask(msg_sw->ts_windowfd, &im, &im, WIN_NULLLINK);
  1855. X    msg_sw->ts_io.tio_selected = msg_io;
  1856. X    msg_sw->ts_io.tio_handlesigwinch = msgwin_handlesigwinch;
  1857. X
  1858. X    /* tty subwindow */
  1859. X    if (!(tty_sw = ttytlsw_createtoolsubwindow(tool, "tty_sw",
  1860. X    TOOL_SWEXTENDTOEDGE, 0, (char **)0)))
  1861. X    perror("tty_sw"), cleanup(0);
  1862. X    ttysw_handlesigwinch(tty_sw);
  1863. X    win_setcursor(tty_sw->ts_windowfd, &write_cursor);
  1864. X
  1865. X    (void) sprintf(blank, "%128c", ' ');
  1866. X    (void) signal(SIGWINCH, sigwinchcatcher);
  1867. X    (void) signal(SIGTERM, sigtermcatcher);
  1868. X    (void) signal(SIGCHLD, sigchldcatcher);
  1869. X    pw_writebackground(hdr_win, 0,0, hdr_rect.r_width, hdr_rect.r_height,
  1870. X               PIX_CLR);
  1871. X    if (ioctl(0, TIOCGETC, &tchars))
  1872. X    perror("gtty failed"), cleanup(0);
  1873. X    win_numbertoname (0, buf1);
  1874. X    if ((rootfd = open(buf1, 0)) == -1)
  1875. X    error("can't open %s", buf1), cleanup(0);
  1876. X    if (fstat(rootfd, &rootbuf))
  1877. X    error("can't stat %s", buf1), cleanup(0);
  1878. X    for (parentfd = 3; parentfd < rootfd; parentfd++)
  1879. X    if (fstat(parentfd, &tmpbuf))
  1880. X        error("Can't stat fd-%d", parentfd);
  1881. X    else if (tmpbuf.st_ino == rootbuf.st_ino) {
  1882. X        (void) close(rootfd);
  1883. X        rootfd = parentfd;
  1884. X        break;
  1885. X    }
  1886. X    istool = 2;
  1887. X    (void) do_version();
  1888. X    lock_cursors();
  1889. X    tool_install(tool);
  1890. X    tool_display(tool);
  1891. X    do_clear();
  1892. X}
  1893. END_OF_FILE
  1894. if test 4177 -ne `wc -c <'tool.c'`; then
  1895.     echo shar: \"'tool.c'\" unpacked with wrong size!
  1896. fi
  1897. # end of 'tool.c'
  1898. fi
  1899. echo shar: End of archive 2 \(of 14\).
  1900. cp /dev/null ark2isdone
  1901. MISSING=""
  1902. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ; do
  1903.     if test ! -f ark${I}isdone ; then
  1904.     MISSING="${MISSING} ${I}"
  1905.     fi
  1906. done
  1907. if test "${MISSING}" = "" ; then
  1908.     echo You have unpacked all 14 archives.
  1909.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1910. else
  1911.     echo You still need to unpack the following archives:
  1912.     echo "        " ${MISSING}
  1913. fi
  1914. ##  End of shell archive.
  1915. exit 0
  1916.